/*
 * copyright (c) 2009 Alexandr [Sn@ble] Surnin
 *
 * This file is part of FrameSeeker.
 *
 * FrameSeeker is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FrameSeeker is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You can read the full version of GNU LGPL in
 * http://www.gnu.org/copyleft/lesser.html
 */


#include "FSHist.h"

FSHist::FSHist() {

    image = NULL;
}


FSHist::FSHist(QImage *_image) {

    setImage(_image);
}


void FSHist::setImage(QImage *_image) {

    image = _image;
}


void FSHist::calculate() {

    // Create pixel descriptor
    struct pixel {
        quint8 a;
        quint8 r;
        quint8 g;
        quint8 b;
    } *pixelPtr,
      *pixelEnd;


    // Initialize colour arrays
    memset(red, 0, sizeof(quint64)*256*3);

    // Calculate pixel count
    quint64 w = image->width();
    quint64 h = image->height();
    quint64 pixelCount = w * h;

    // Find pixel array end
    pixelEnd = (pixel*)image->bits() + pixelCount;

    // Generate histogram
    for (pixelPtr = (pixel*)image->bits(); pixelPtr <= pixelEnd; pixelPtr++) {
        red  [pixelPtr->r]++;
        green[pixelPtr->g]++;
        blue [pixelPtr->b]++;
    }


    quint64 maxR = 0,
            maxG = 0,
            maxB = 0;

    // Find maximums
    for (int i = 0; i < 256; i++) {
        maxR = (maxR < red[i])   ? red[i]   : maxR;
        maxG = (maxG < green[i]) ? green[i] : maxG;
        maxB = (maxB < blue[i])  ? blue[i]  : maxB;
    }

    // Maximum level is 256
    maxR >>= 8; // devide by 256
    maxG >>= 8;
    maxB >>= 8;

    // Normalize histograms
    for (int i = 0; i < 256; i++) {
        red[i]   /= maxR;
        green[i] /= maxG;
        blue[i]  /= maxB;

        red[i] =   red[i]   - red[i]   % 16;
        green[i] = green[i] - green[i] % 16;
        blue[i] =  blue[i]  - blue[i]  % 16;
    }

}

quint64 FSHist::r(int index) {

    return red[index];
}



quint64 FSHist::g(int index) {

    return green[index];
}



quint64 FSHist::b(int index) {

    return blue[index];
}


